﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Windows.Forms;
using CloudDetector.Algorithms;
using CloudDetector.RasterMap;
using CloudDetector.Utils;

namespace CloudDetector.GUI
{
    #region Nested Types

    /// <summary>
    /// Vektorműveletek gyűjteménye.
    /// </summary>
    public enum VectorOperations { Create, Select };

    #endregion

    /// <summary>
    /// A felhődetektáló program főablak osztálya.
    /// </summary>
    public partial class MainForm : Form
    {
        #region Fields

        private Map rasterMap;
        private Point lastMousePos;
        private Boolean movementMode;
        int[] Thresholds;
        private HistogramDialog mHistDialog;
        private int[,] mValueHistogram;

        #region ImageLayers

        ImageLayers Layers;
        ImageLayers TCResult;
        ImageLayers OtsuResult;
        ImageLayers Cloud;
        ImageLayers Shadow;
        ImageLayers Result;

        #endregion

        #region Vector Definition Fields

        private PictureBoxStatus mStatus;
        private VectorOperations mVectOp;
        private LocalVector mStart, mCurrent;
        private double mRasterMapZoomLevel;
        private LocalVector mNormVect;
        private double mVectMagn;

        #endregion

        #endregion

        #region Properties

        /// <summary>
        /// Beállítja vagy visszaadja a megjelenítő <see cref="MapPictureBox"/> állapotát.
        /// </summary>
        private PictureBoxStatus Status
        {
            get { return mStatus; }
            set { mStatus = value; }
        }

        /// <summary>
        /// Beállítja vagy visszaadja az aktuális vektorműveletet.
        /// </summary>
        public VectorOperations VectOp
        {
            get { return mVectOp; }
            set
            {
                if (value == VectorOperations.Create)
                {
                    mapPictureBox.InitVector();
                    BtnDraw.Enabled = true;
                }
                mVectOp = value;
            }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// A konzolos indítási mód konstruktora.
        /// </summary>
        /// <param name="input1">Első bementi kép.</param>
        /// <param name="input2">Második bemeneti kép.</param>
        /// <param name="output1">Első kimeneti kép.</param>
        /// <param name="output2">Második kimeneti kép.</param>
        public MainForm(string input1, string input2, string output1, string output2)
        {
            Bitmap pict123, pict457;
            CommandLineRun(input1, input2, out pict123, out pict457);
            pict123.Save(output1, ImageFormat.Tiff);
            pict457.Save(output2, ImageFormat.Tiff);
        }

        /// <summary>
        /// Grafikus indítási mód konstruktora.
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            Status = PictureBoxStatus.Neutral;
            VectOp = VectorOperations.Select;
            navigatorControl.Enabled = false;
            toolStripStatusLabel.Text = "Kérem válasszon futási módot!";

            //indexek beállítása
            afterTCGroupBox.Controls.SetChildIndex(tcBrightnessRadioButton, 0);
            afterTCGroupBox.Controls.SetChildIndex(tcWettnesRadioButton, 1);
            afterTCGroupBox.Controls.SetChildIndex(tcHazinessRadioButton, 2);
            afterTCGroupBox.Controls.SetChildIndex(tcOriginalRadioButton, 3);

            afterOtsuGroupBox.Controls.SetChildIndex(oBrightnessRadioButton, 0);
            afterOtsuGroupBox.Controls.SetChildIndex(oWettnesRadioButton, 1);
            afterOtsuGroupBox.Controls.SetChildIndex(oHazinessRadioButton, 2);
            afterOtsuGroupBox.Controls.SetChildIndex(oCloudsRadioButton, 3);
            afterOtsuGroupBox.Controls.SetChildIndex(oShadowsRadioButton, 4);
            afterOtsuGroupBox.Controls.SetChildIndex(oThematicClRadioButton, 5);

            mapPictureBox.MouseDown += new MouseEventHandler(mapPictureBox_MouseDown);
            mapPictureBox.MouseUp += new MouseEventHandler(mapPictureBox_MouseUp);
            mapPictureBox.MouseMove += new MouseEventHandler(mapPictureBox_MouseMove);

            if (DialogResult.Yes == MessageBox.Show("Szeretne automatikusan felhőt detektálni?", "Futási mód", MessageBoxButtons.YesNo))
            {
                AutomaticModeController();
            }
            else
                ManualModeInitializer();
        }

        #endregion

        #region Event Handlers

        #region Menu Event Handlers

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void loadMapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!saveResultToolStripMenuItem.Enabled && Layers!=null)
            {
                MessageBox.Show("Amíg nem futatta le az összes algoritmust nem tölthet be új képeket!");
                return;
            }
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = true;
            ofd.Filter = "Tagged Images(*.tif, *.tiff) | *.tif;*.tiff";
            ofd.Title = "Képfájlok betöltése";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                if (ofd.FileNames.Length != 2)
                {
                    toolStripStatusLabel.Text = "Pontosan 2 db tiff fájlt várok! Próbálja újra.";
                    return;
                }
                else
                {
                    Bitmap Picture1, Picture2;
                    //képek importálása
                    try
                    {
                        Picture1 = new Bitmap(ofd.FileNames[0]);
                        Picture2 = new Bitmap(ofd.FileNames[1]);
                    }
                    catch (Exception)
                    {
                        toolStripStatusLabel.Text = "Nem sikerült megnyitnom a fájlokat! Próbálja újra.";
                        return;
                    }
                    Layers = new ImageLayers(Picture1, Picture2);

                    try
                    {
                        SetRasterMapOnMapPictureBox(Picture1);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                    navigatorControl.Enabled = true;
                    vectorGroupBox.Enabled = true;
                    layerSetGroupBox.Enabled = true;
                    BtnTasseled.Enabled = true;
                    toolStripStatusLabel.Text = "Képek betöltve. Készen állunk a következő fázisra.";
                    
                    //már volt egyszer futtatva
                    if (TCResult != null)
                    {
                        TCResult = Cloud = Shadow = Result = null;
                        afterOtsuGroupBox.Enabled = afterTCGroupBox.Enabled = heGroupBox.Enabled = false;
                        heProgressBar.Value = 0;
                    }
                }
            }
        }

        private void saveResultToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Tagged Images(*.tif, *.tiff)|*.tif; *.tiff";
            sfd.Title = "Eredmény mentése";
            sfd.DefaultExt = "tif";
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                Bitmap pict123, pict457;
                Result.CreateImage(out pict123, out pict457);
                string filepath = sfd.FileName.Substring(0, sfd.FileName.Length - 4);

                pict123.Save(filepath + "_123.tif", ImageFormat.Tiff);
                pict457.Save(filepath + "_457.tif", ImageFormat.Tiff);

                toolStripStatusLabel.Text = "Eredményképek elmentve!";
            }
        }

        #endregion

        #region Mouse Event Handlers on PictureBox

        void mapPictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (mStatus == PictureBoxStatus.Neutral && movementMode && rasterMap != null)
            {
                rasterMap.Move(lastMousePos.X - e.X, lastMousePos.Y - e.Y);
                lastMousePos = e.Location;
            }
            else if (mStatus == PictureBoxStatus.Draw && movementMode)
            {
                mCurrent = new LocalVector(e.X, e.Y);
                if (VectOp == VectorOperations.Create)
                {
                    mapPictureBox.Vector.EndVertex = mCurrent;
                }
                mapPictureBox.Refresh();
            }
        }

        void mapPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            if (mStatus == PictureBoxStatus.Neutral)
            {
                mapPictureBox.Cursor = System.Windows.Forms.Cursors.Arrow;
                movementMode = false;
            }
            else
            {
                if (VectOp == VectorOperations.Create)
                {
                    mapPictureBox.Vector.StartVertex = mStart;
                    mapPictureBox.Vector.EndVertex = mCurrent;
                }
                movementMode = false;
            }
        }

        void mapPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            if (mStatus == PictureBoxStatus.Neutral)
            {
                mapPictureBox.Cursor = System.Windows.Forms.Cursors.SizeAll;
                movementMode = true;
                lastMousePos = e.Location;
            }
            else
            {
                mStart = new LocalVector(e.X, e.Y);
                movementMode = true;

                if (e.Button == MouseButtons.Left && VectOp == VectorOperations.Create)
                {
                    mapPictureBox.Vector.StartVertex = mStart;
                    mapPictureBox.Vector.EndVertex = mStart;
                }
                if (e.Button == MouseButtons.Left && VectOp == VectorOperations.Select)
                {
                    mapPictureBox.Vector.Select(e.Location);
                }
                mapPictureBox.Refresh();
            }
        }

        #endregion

        #region Vector Definition Event Handlers

        private void BtnDraw_Click(object sender, EventArgs e)
        {
            if (VectOp == VectorOperations.Select)
            {
                VectOp = VectorOperations.Create;
                Status = mapPictureBox.Status = PictureBoxStatus.Draw;
                BtnDraw.Text = "Rögzít";
                BtnDel.Enabled = false;
            }
            else if (VectOp == VectorOperations.Create)
            {
                VectOp = VectorOperations.Select;
                Status = PictureBoxStatus.Neutral;
                BtnDraw.Text = "Rajzolás";
                BtnSelect.Enabled = true;
                BtnDraw.Enabled = false;
                RecordVectorDatas();
            }
        }

        private void BtnSelect_Click(object sender, EventArgs e)
        {
            VectOp = VectorOperations.Select;
            Status = PictureBoxStatus.Draw;
            BtnDel.Enabled = true;
        }

        private void BtnDel_Click(object sender, EventArgs e)
        {
            if (mapPictureBox.Vector.Selected)
            {
                mapPictureBox.InitVector();
                BtnSelect.Enabled = false;
                BtnDel.Enabled = false;
                BtnDraw.Enabled = true;
                mapPictureBox.Refresh();
                ClearVectorDatas();
            }
        }

        #endregion

        #region Cloud Detection Process Event Handlers

        private void BtnTasseled_Click(object sender, EventArgs e)
        {
            //kiszámolja a tc-t
            TasseledCap TC = new TasseledCap();
            TCResult = new ImageLayers(TC.Calc(Layers));

            //megjeleníti a br sávot
            SetRasterMapOnMapPictureBox(TCResult.CreateGrayScale(0));

            //engedjük, hogy válasszon a sávok között vagy elindítsa az otsut
            afterTCGroupBox.Enabled = true;
            BtnOtsu.Enabled = true;
            layerSetGroupBox.Enabled = false;
            //vectorGroupBox.Enabled = false;
            //mapPictureBox.Status = PictureBoxStatus.Neutral;
            //mapPictureBox.Refresh();
            tcBrightnessRadioButton.Checked = true;
            //csak egyszer legyen futatható
            BtnTasseled.Enabled = false;
            toolStripStatusLabel.Text = "Tasseled Cap transzformáció sikeresen végrehajtva. Készen állunk a következő fázisra.";
        }

        private void BtnOtsu_Click(object sender, EventArgs e)
        {
            Otsu O = new Otsu(TCResult);
            Thresholds = O.Thresholding(out OtsuResult, out Cloud);
            Cloud.CleanCloud();

            if (!mNormVect.Equals(null))
            {
                ShadowDetector SD = new ShadowDetector(mRasterMapZoomLevel, mNormVect, mVectMagn);
                Shadow = SD.Detect(Cloud);
            }

            //megjeleníti a br sávot küszöbölve
            SetRasterMapOnMapPictureBox(OtsuResult.CreateGrayScale(0));

            if (Shadow == null)
                mValueHistogram = Layers.Masking(Cloud);
            else
                mValueHistogram = Layers.Masking(Shadow);

            //engedjük, hogy válasszon a sávok között vagy elindítsa az otsut
            afterOtsuGroupBox.Enabled = true;
            trsSliderPanel.Enabled = true;
            heGroupBox.Enabled = true;
            oBrightnessRadioButton.Checked = true;
            //BtnMasking.Enabled = true;
            vectorGroupBox.Enabled = false;
            mapPictureBox.Status = PictureBoxStatus.Neutral;
            mapPictureBox.Refresh();
            BtnOtsu.Enabled = false;
            BtnHe.Enabled = true;
            toolStripStatusLabel.Text = "Otsu köszöbölés sikeresen végrehajtva. Készen állunk a következő fázisra.";
        }

        //a tc által kiszámolt 3 sáv közül jeleníti meg a kiválaszottat
        private void Tasseled_radioButton_CheckedChanged(object sender, EventArgs e)
        {
            //2* hívodik meg: a régin és az újon...
            if (!((RadioButton)sender).Checked)
                return;

            //ha egy otsu eredményről kattint vissza
            if (afterOtsuGroupBox.Enabled)
            {
                foreach (RadioButton Rb in afterOtsuGroupBox.Controls)
                {
                    if (Rb.Checked)
                    {
                        Rb.Checked = false;
                        break;
                    }
                }
                trsSliderPanel.Enabled = false;
            }


            if (ResultRadioButton.Checked)
                ResultRadioButton.Checked = false;


            int Index = afterTCGroupBox.Controls.GetChildIndex((RadioButton)sender);
            //ha a tc eredményét választotta ki
            if (Index < 3)
            {
                layerSetGroupBox.Enabled = false;
                try
                {
                    SetRasterMapOnMapPictureBox(TCResult.CreateGrayScale(Index));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            //ha ez eredeti képet
            else if (Index == 3)
            {
                layerSetGroupBox.Enabled = true;
                int R = (int)redLayerNumericUpDown.Value - 1; //0-tól indexelünk ezért -1
                int G = (int)greenLayerNumericUpDown.Value - 1;
                int B = (int)blueLayerNumericUpDown.Value - 1;
                try
                {
                    SetRasterMapOnMapPictureBox(Layers.CreateRGB(R, G, B));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }

        }

        //a otsu által kiszámolt 3 sáv közül jeleníti meg a kiválaszottat
        private void Otsu_radioButton_CheckedChanged(object sender, EventArgs e)
        {
            //2* hívodik meg: a régin és az újon...
            if (!((RadioButton)sender).Checked)
                return;

            //ha egy otsu eredményről kattint ide
            foreach (RadioButton Rb in afterTCGroupBox.Controls)
            {
                if (Rb.Checked)
                {
                    Rb.Checked = false;
                    break;
                }
            }

            if (ResultRadioButton.Checked)
                ResultRadioButton.Checked = false;

            int Index = afterOtsuGroupBox.Controls.GetChildIndex((RadioButton)sender);

            //formon lévő vezérlők tiltása/engedélyezése
            layerSetGroupBox.Enabled = (Index < 5) ? false : true;
            trsSliderPanel.Enabled = (Index < 3) ? true : false;
            if (Index < 3)//nem a felhő van kiválasztva
            {
                //ha le lett volna tilt a felhő miatt
                trsSliderPanel.Enabled = true;

                trsholdtrackBar.Value = Thresholds[Index];
                trsholdLabel.Text = trsholdtrackBar.Value.ToString();
                try
                {
                    SetRasterMapOnMapPictureBox(OtsuResult.CreateGrayScale(Index));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else if (Index == 3)//ha felhő van kiválasztva
            {
                try
                {
                    SetRasterMapOnMapPictureBox(Cloud.CreateGrayScale(0));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else if (Index == 4) // ha az árnyék van kiválasztva
            {
                trsSliderPanel.Enabled = false;

                try
                {
                    SetRasterMapOnMapPictureBox(Shadow.CreateGrayScale(0));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
            else if (Index == 5)  //ha a felhő tematikus kép van kiválasztva
            {
                int R = (int)redLayerNumericUpDown.Value - 1; //0-tól indexelünk ezért -1
                int G = (int)greenLayerNumericUpDown.Value - 1;
                int B = (int)blueLayerNumericUpDown.Value - 1;
                try
                {
                    if (Shadow==null)
                        SetRasterMapOnMapPictureBox(Layers.MaskedOriginals(Cloud, R, G, B));
                    else
                        SetRasterMapOnMapPictureBox(Layers.MaskedOriginals(Shadow, R, G, B));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }

        private void ResultRadioButton_CheckedChanged(object sender, EventArgs e)
        {
            if (!((RadioButton)sender).Checked)
                return;

            //ha egy otsu eredményről kattint ide
            foreach (RadioButton Rb in afterTCGroupBox.Controls)
            {
                if (Rb.Checked)
                {
                    Rb.Checked = false;
                    break;
                }
            }

            //ha egy otsu eredményről kattint vissza

            foreach (RadioButton Rb in afterOtsuGroupBox.Controls)
            {
                if (Rb.Checked)
                {
                    Rb.Checked = false;
                    break;
                }
            }
            trsSliderPanel.Enabled = false;

            layerSetGroupBox.Enabled = true;
            int R = (int)redLayerNumericUpDown.Value - 1; //0-tól indexelünk ezért -1
            int G = (int)greenLayerNumericUpDown.Value - 1;
            int B = (int)blueLayerNumericUpDown.Value - 1;
            try
            {
                if (Shadow == null)
                    SetRasterMapOnMapPictureBox(Result.CreateRGB(R, G, B));
                else
                    SetRasterMapOnMapPictureBox(Result.CreateRGB(R, G, B));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        //csak a forrás és a végeredmény képekre!
        private void BtnOk_Click(object sender, EventArgs e)
        {
            int R = (int)redLayerNumericUpDown.Value - 1; //0-tól indexelünk ezért -1
            int G = (int)greenLayerNumericUpDown.Value - 1;
            int B = (int)blueLayerNumericUpDown.Value - 1;
            try
            {
                //ha az eredeti kép van megjelenítve
                if (tcOriginalRadioButton.Checked)
                    SetRasterMapOnMapPictureBox(Layers.CreateRGB(R, G, B));
                else if (oThematicClRadioButton.Checked)
                {
                    if (Shadow == null)
                        SetRasterMapOnMapPictureBox(Layers.MaskedOriginals(Cloud, R, G, B));
                    else
                        SetRasterMapOnMapPictureBox(Layers.MaskedOriginals(Shadow, R, G, B));
                }
                else if (ResultRadioButton.Checked)
                    SetRasterMapOnMapPictureBox(Result.CreateRGB(R, G, B));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        /*
        private void BtnMasking_Click(object sender, EventArgs e)
        {
            if (Shadow == null)
                mValueHistogram = Layers.Masking(Cloud);
            else
                mValueHistogram = Layers.Masking(Shadow);

            layerSetGroupBox.Enabled = true;
            int R = (int)redLayerNumericUpDown.Value - 1; //0-tól indexelünk ezért -1
            int G = (int)greenLayerNumericUpDown.Value - 1;
            int B = (int)blueLayerNumericUpDown.Value - 1;
            try
            {
                if (Shadow == null)
                    SetRasterMapOnMapPictureBox(Layers.GetValueData(Cloud).CreateRGB(R, G, B));
                else
                    SetRasterMapOnMapPictureBox(Layers.GetValueData(Shadow).CreateRGB(R, G, B));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        */
        private void BtnHist_Click(object sender, EventArgs e)
        {
            if (mHistDialog != null)
                mHistDialog.Dispose();

                mHistDialog = new HistogramDialog(mValueHistogram);
                mHistDialog.Show();
        }

        private void BtnHe_Click(object sender, EventArgs e)
        {
            HE histEquilization = new HE();
            Result = histEquilization.EquilizeHistogram(mValueHistogram, Layers, heProgressBar);
            mValueHistogram = Result.Histograms();
            layerSetGroupBox.Enabled = true;
            int R = (int)redLayerNumericUpDown.Value - 1; //0-tól indexelünk ezért -1
            int G = (int)greenLayerNumericUpDown.Value - 1;
            int B = (int)blueLayerNumericUpDown.Value - 1;
            try
            {
                SetRasterMapOnMapPictureBox(Result.CreateRGB(R, G, B));
                ResultRadioButton.Checked = true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            saveResultToolStripMenuItem.Enabled = true;
            ResultRadioButton.Enabled = true;
            BtnHe.Enabled = false;

            if (mHistDialog != null && mHistDialog.IsDisposed)
                BtnHist_Click(this, new EventArgs());
            else
                mHistDialog.Histogram = mValueHistogram;
        }

        private void trsholdtrackBar_ValueChanged(object sender, EventArgs e)
        {
            int Index = 0;
            //megkeresni melyik radioButton van kijelölve
            for (int i = 0; i < 3; ++i)
            {
                if (((RadioButton)afterOtsuGroupBox.Controls[i]).Checked)
                {
                    Index = i;
                    break;
                }
            }
            Thresholds[Index] = trsholdtrackBar.Value;
            trsholdLabel.Text = trsholdtrackBar.Value.ToString();
            TCResult.RecalcThresholdedLayer(Thresholds[Index], Index, ref OtsuResult);

            Cloud = OtsuResult.CreateCloud(Thresholds);
            ShadowDetector SD = new ShadowDetector(mRasterMapZoomLevel, mNormVect, mVectMagn);
            Shadow = SD.Detect(Cloud);

            try
            {
                SetRasterMapOnMapPictureBox(OtsuResult.CreateGrayScale(Index));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #endregion

        #endregion

        #region Member Methods

        #region Running Mode Methods

        /// <summary>
        /// Automatikus üzemmód kiválasztása esetén ez az irányító metódus ütemezi be
        /// a felhődetektálási munkafolyamatokat.
        /// </summary>
        private void AutomaticModeController()
        {
            toolStripStatusLabel.Text = "Automatikus üzemmód kiválasztva!";
            // load images
            loadMapToolStripMenuItem_Click(this, new EventArgs());
            // automatikus futás
            RunAutomaticProcess();
            // megjelenítés
            toolStripStatusLabel.Text = "Munkafolyamatok elvégezve!";
            layerSetGroupBox.Enabled = true;
            int R = (int)redLayerNumericUpDown.Value - 1; //0-tól indexelünk ezért -1
            int G = (int)greenLayerNumericUpDown.Value - 1;
            int B = (int)blueLayerNumericUpDown.Value - 1;
            try
            {
                SetRasterMapOnMapPictureBox(Layers.CreateRGB(R, G, B));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            saveResultToolStripMenuItem.Enabled = true;
            vectorGroupBox.Enabled = false;
            algorithmsGroupBox.Enabled = false;
            this.Activate();
        }

        /// <summary>
        /// Manuális üzemmód kiválasztása esetén ez a metódus készíti elő a főablakot.
        /// </summary>
        private void ManualModeInitializer()
        {
            loadMapToolStripMenuItem.Enabled = true;
            toolStripStatusLabel.Text = "Manuális üzemmód kiválasztva! A fájl menüből tudja betölteni a képeket!";
        }

        /// <summary>
        /// Parancssoros futtatás. Beolvassa a megadott képeket, elvégzi a felhődetektálás
        /// és az eredményeket a megadott helyre menti.
        /// </summary>
        /// <param name="input1">Első bemenő kép.</param>
        /// <param name="input2">Második bemenő kép.</param>
        /// <param name="destPict1">Első eredmény kép.</param>
        /// <param name="destPict2">Második eredmény kép.</param>
        private void CommandLineRun(string input1, string input2, out Bitmap destPict1, out Bitmap destPict2)
        {
            Bitmap srcPict1 = new Bitmap(input1);
            Bitmap srcPict2 = new Bitmap(input2);
            Layers = new ImageLayers(srcPict1, srcPict2);
            RunAutomaticProcess();
            Layers.CreateImage(out destPict1, out destPict2);
        }

        /// <summary>
        /// Felhődetektálási munkafolyamatok szekvenciáját meghívó metódus.
        /// </summary>
        private void RunAutomaticProcess()
        {
            // tasseled cap
            TasseledCap TC = new TasseledCap();
            TCResult = new ImageLayers(TC.Calc(Layers));
            // otsu
            Otsu O = new Otsu(TCResult);
            Thresholds = O.Thresholding(out OtsuResult, out Cloud);
            Cloud.CleanCloud();
            // histogram equilization
            if (Shadow == null)
                mValueHistogram = Layers.Masking(Cloud);
            else
                mValueHistogram = Layers.Masking(Shadow);
            HE histEquilization = new HE();
            Result = histEquilization.EquilizeHistogram(mValueHistogram, Layers, heProgressBar);
        }

        #endregion

        /// <summary>
        /// A berajzolt vektor adatainak mentése.
        /// </summary>
        private void RecordVectorDatas()
        {
            mVectMagn = mapPictureBox.Vector.Magnitude();
            mNormVect = mapPictureBox.Vector.Normalize().Cut();
            mRasterMapZoomLevel = rasterMap.Zoomlevel;
            normLabel.Text = mNormVect.ToString();
            magnLabel.Text = mVectMagn.ToString("0.00", CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// A berajzolt vektor adatainak törlése.
        /// </summary>
        private void ClearVectorDatas()
        {
            mRasterMapZoomLevel = 0;
            mVectMagn = 0;
            mNormVect = new LocalVector();
            normLabel.Text = "null";
            magnLabel.Text = "0";
        }

        /// <summary>
        /// Megjelenítendő kép beállítása.
        /// </summary>
        /// <param name="map">A megjelenítendő kép.</param>
        private void SetRasterMapOnMapPictureBox(Bitmap map)
        {
            rasterMap = new Map(map);
            rasterMap.ZoomDisplay = mapPictureBox;
            navigatorControl.RasterMap = rasterMap;
        }

        #endregion
    }
}
